home *** CD-ROM | disk | FTP | other *** search
- Path: news.th-darmstadt.de!news!enno
- From: enno@inferenzsysteme.informatik.th-darmstadt.de (Enno Sandner)
- Newsgroups: comp.lang.c++
- Subject: Re: Two way communication between objects
- Date: 28 Jan 1996 10:06:52 GMT
- Organization: Fachbereich Informatik, TH Darmstadt
- Distribution: world
- Message-ID: <ENNO.96Jan28110653@kitz.inferenzsysteme.informatik.th-darmstadt.de>
- References: <310ACCE2.2600@werple.mira.net.au>
- NNTP-Posting-Host: kitz.intellektik.informatik.th-darmstadt.de
- In-reply-to: Ross Forder's message of Sun, 28 Jan 1996 11:09:54 +1000
-
- In article <310ACCE2.2600@werple.mira.net.au> Ross Forder <erosco@werple.mira.net.au> writes:
-
- I have to apologise what what is probably a stupid question but I'm only
- a beginner at some of this stuff.
-
- I am trying to write a VERY simple client and server set of objects. I
- would like to client to register with the server at ctor time and have
- the server know about the client by saving a pointer to the client
- so he can callback to a method called say 'event'.
-
- The problem is the fact that they will both need a pointer to each other
- and this seems impossible using strong typing. Is there a simple 'object
- oriented' way to do this?
-
- I have been able to make this work by having the server only know about
- a parent class of the client (say eventhandler) but this is still not a
- bulletproof solution.
-
- Can someone set me straight?
-
- For circular dependent references one need a so-called forward declaration
-
- struct B; // declare B ('There is a class B')
- struct A { B* b_; }; // define A ('A looks like ...')
- struct B { A* a_; }; // define B ('B looks like ...')
-
- In A's definition it's already known that there is a class called 'B'.
- So the compiler will not complain about the 'not-yet-defined' class as
- long you don't try to access members of B in the definition of 'A'.
- These sort of circular dependency can often be avoided when you introduce
- an abstract class. A possible solution to your problem (or better a direct
- assembly from your description ...) may look like:
- ---
- #include <iostream.h>
-
- class Server;
-
- class Client {
- public:
- virtual ~Client() {}
- virtual void Event()=0;
- virtual Server& CreateServer()=0;
- };
-
- class Server {
- public:
- Server(Client& cb) : cb_(cb) {}
- void NotifyClient() { cb_.Event(); }
- private:
- Client& cb_;
- };
-
- class ConcrClient : public Client {
- public:
- void Event() { cout << "Event\n"; }
- Server& CreateServer() { return *new Server(*this); }
- };
-
- int main()
- {
- ConcrClient client;
- Server& server=client.CreateServer();
- server.NotifyClient();
- delete &server;
-
- return 0;
- }
-
- ---
- The abstract class 'Client' defines the common interface of all clients.
- Thus every client needs an 'Event' member-function. The server accesses
- them only through that interface, so it's easy to add new sorts of clients.
- There are more flexible ways to implement callbacks, e.g. the 'Command'
- pattern described in the 'Design Patterns' book.
-
- Enno
-